﻿using MultiAgentsServer.Pages;
using MultiAgentsServer.Scripts.Database;
using MultiAgentsServer.Scripts.Hubs;
using MultiAgentsServer.Scripts.Services;
using MultiAgentsServer.Scripts.Services.DataModels;
using MultiAgentsShared;

namespace MultiAgentsServer
{
    class Program
    {
        static void Main(string[] args)
        {
            SetupDI(args);
        }

        private static void SetupDI(string[] args)
        {
            WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
#if LOCALDEV
            builder.Configuration.AddJsonFile("appsettings.LocalDev.json");
#elif DEVELOP
            builder.Configuration.AddJsonFile("appsettings.Develop.json");
#elif RELEASE
            builder.Configuration.AddJsonFile("appsettings.Release.json");
#endif
            //TODO: AddSingleton to scoped
            builder.Services.AddSingleton<IEventBus, EventBus>();

            // Add services to the container.
            builder.Services.AddRazorPages();
            builder.Services.AddSession(options =>
            {
                options.IdleTimeout = TimeSpan.FromMinutes(30);
                options.Cookie.HttpOnly = true;
                options.Cookie.IsEssential = true;
            });
            builder.Services.AddAuthentication("CookieAuth").AddCookie("CookieAuth", options =>
            {
                options.Cookie.HttpOnly = true;
                options.LoginPath = "/Index";
                options.ExpireTimeSpan = TimeSpan.FromMinutes(30);
            });

            builder.Services.AddSignalR(hubOptions =>
            {
                hubOptions.EnableDetailedErrors = true;
                //hubOptions.KeepAliveInterval = TimeSpan.FromMinutes(1); // Set the frequency at which the server sends KeepAlive messages to ensure the connection stays active.
                hubOptions.MaximumReceiveMessageSize = 20 * 1024 * 1024; // 20 MB
            });

            builder.Services.AddHttpClient();

            // Register your custom services with the DI container.
            // Scoped lifetime is often a good default for web apps.
            builder.Services.AddSingleton<OpenAIComService>();
            builder.Services.AddSingleton<OllamaComService>();
            builder.Services.AddSingleton<LlmComEntryPoint>();
            builder.Services.AddSingleton<FunctionCallerService>();
            builder.Services.AddSingleton<ToolSetCollection>();
            builder.Services.AddSingleton<ChatContextManager>();
            builder.Services.AddSingleton<OthersManager>();
            builder.Services.AddSingleton<BehaviorTreeService>();
            builder.Services.AddSingleton<AgentService>();
            builder.Services.AddSingleton<WebhookService>();
            builder.Services.AddSingleton<UserPermissionManagementModel>();
            builder.Services.AddSingleton<InviteManagerModel>();
            #region DataModel
            builder.Services.AddSingleton<UserCookieDataModel>();
            #endregion

            #region Database Related Config
            builder.Services.AddSingleton<DatabaseRepository>();
            builder.Services.AddSingleton<DataBaseOperationService>();
            builder.Services.AddSingleton<DataBaseConnectService>();
            #endregion

            WebApplication app = builder.Build();

            IConfiguration configuration = app.Services.GetRequiredService<IConfiguration>();
            DatabaseInitializer dbInitializer = new(configuration);
            dbInitializer.Initialize();

            #region SignalR Related Config
            // Configure the HTTP request pipeline.
            if (!app.Environment.IsDevelopment())
            {
                app.UseExceptionHandler("/Error");
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseStaticFiles();
            app.UseRouting();
            app.UseAuthorization();
            app.MapRazorPages();
            app.MapControllers();
            app.MapHub<SignalRChatHub>("/chatHub");
            app.MapHub<SignalRUserHub>("/userHub");
            app.MapHub<SignalRWorkflowHub>("/WorkflowHub");
            app.MapHub<SignalRUserSettingsHub>("/userSettingsHub");
            app.MapHub<SignalRAgentHub>("/AgentHub");

            //force instance of chatContextManager
            ChatContextManager? initializationService = app.Services.GetService<ChatContextManager>();
            OthersManager? initializationOthersManager = app.Services.GetService<OthersManager>();
            BehaviorTreeService? initializationWorkflowConfigService = app.Services.GetService<BehaviorTreeService>();
            AgentService? agentService = app.Services.GetService<AgentService>();
            WebhookService? initializationWebhookService = app.Services.GetService<WebhookService>();

            app.Run();
            #endregion
        }
    }
}